package br.ufpe.cin.vspeed.view;

import java.io.InputStream;

import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.util.FileManager;

/**
 * This class is the super class of specific converter classes.
 * <p/>
 * Project OWL2Prefuse <br/>
 * Converter.java created 2 januari 2007, 10:41
 * <p/>
 * Copyright &copy 2006 Jethro Borsje
 * 
 * @author <a href="mailto:info@jborsje.nl">Jethro Borsje</a>
 * @version $$Revision:$$, $$Date:$$
 */
public class Converter {
	/**
	 * The Jena model that needs to be converted to Prefuse.
	 */
	protected OntModel m_model;

	/**
	 * Creates a new instance of Converter.
	 * 
	 * @param p_OWLFile
	 *            The path to the OWL file which needs to be converted.
	 */
	public Converter(final String p_OWLFile) {
		load(p_OWLFile);

		// Normalize the model.
		OWLNormalize();
	}

	/**
	 * Creates a new instance of Converter.
	 * 
	 * @param p_model
	 *            The Jena OntModel that needs to be converted.
	 */
	public Converter(final OntModel p_model) {
		this.m_model = p_model;

		// Normalize the model.
		OWLNormalize();
	}

	/**
	 * Get all the classes inthe ontology which do not have a superclass and link them to owl:Thing.
	 */
	protected void OWLNormalize() {
		// The SPARQL query.
		final String strQuery = "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>"
				+ "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>"
				+ "PREFIX owl: <http://www.w3.org/2002/07/owl#>" + "SELECT ?x" + "{" + "?x rdf:type owl:Class ."
				+ "OPTIONAL { ?x rdfs:subClassOf ?y }" + "FILTER (!bound(?y))" + "FILTER (!isBlank(?x))" + "}";

		final Query query = QueryFactory.create(strQuery);
		final QueryExecution qexec = QueryExecutionFactory.create(query, this.m_model);
		final ResultSet rs = qexec.execSelect();

		final OntClass rootClass = this.m_model.getOntClass("http://www.w3.org/2002/07/owl#Thing");
		final Property subClassProp = this.m_model.getProperty("http://www.w3.org/2000/01/rdf-schema#subClassOf");

		while (rs.hasNext()) {
			final Resource resource = rs.nextSolution().getResource("x");
			resource.addProperty(subClassProp, rootClass);
		}
	}

	/**
	 * Import the OWL database file into the Jena ontology model.
	 * 
	 * @param p_OWLFile
	 *            The path to the OWL file which needs to be converted.
	 */
	private void load(final String p_OWLFile) {
		this.m_model = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);

		final InputStream in = FileManager.get().open(p_OWLFile);
		if (in == null) {
			throw new IllegalArgumentException("File: " + p_OWLFile + " not found");
		}

		this.m_model.read(in, "");
	}
}